package com.wangy.sct.common.web.configuration;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.wangy.sct.common.core.InvokeResult;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.util.StreamUtils;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Optional;

/**
 * ClassName: SctHttpMessageConverter <br/>
 * Description:  <br/>
 *
 * @author wangyue
 * @version V1.0.0
 * @date 2018/11/7 12:01 AM
 */
@Configuration
public class GlobalHttpMessageConverter extends AbstractHttpMessageConverter<InvokeResult> {
	public final static Charset UTF8 = Charset.forName("UTF-8");
	private Charset charset = UTF8;
	private SerializerFeature[] features = new SerializerFeature[0];

	public GlobalHttpMessageConverter() {
		super(new MediaType("application", "json"), new MediaType("application", "json", UTF8));
		System.out.println("<<<<<注册SctMessageConverter解析InvokeResult>>>>>");
	}

	@Override
	protected boolean supports(Class<?> aClass) {
		// 只处理InvokeResult类型
		return InvokeResult.class.isAssignableFrom(aClass);
	}

	/**
	 * @Description: 需要对Service返回的InvokeResult<T>进行转换。
	 * 因为不知道T的真实类型，不转换的话会变成JSONObject(FastJson)
	 * @param: [aClass, httpInputMessage]
	 * @return: com.wangy.sct.common.InvokeResult<T>
	 * @author: wangyue
	 * @Date: 2018/11/9 7:43 PM
	 */
	@Override
	protected InvokeResult readInternal(Class<? extends InvokeResult> aClass, HttpInputMessage httpInputMessage) throws IOException, HttpMessageNotReadableException {
		String inputMessage = StreamUtils.copyToString(httpInputMessage.getBody(), UTF8);
		InvokeResult invokeResult = JSON.parseObject(inputMessage, aClass);
		if (null != invokeResult.getRetData()) {
			Optional<String> retDataClassOpt = Optional.ofNullable(invokeResult.getRetDataClass());
			if (invokeResult.getRetData() instanceof JSONObject) {
				System.out.println(">>>>>转换JSONObject");
				retDataClassOpt.ifPresent((className) -> {
					try {
						Class subClass = Class.forName(className);
						JSONObject retData = (JSONObject) invokeResult.getRetData();
						invokeResult.setData(JSON.parseObject(retData.toJSONString(), subClass));
					} catch (ClassNotFoundException e) {
						e.printStackTrace();
					}
				});
			} else if (invokeResult.getRetData() instanceof JSONArray) {
				// TODO
				System.out.println(">>>>>转换JSONArray");

			} else {
				// TODO
				System.out.println(">>>>>需要转换???");
			}
		}
		return invokeResult;
	}


	@Override
	protected void writeInternal(InvokeResult invokeResult, HttpOutputMessage httpOutputMessage) throws IOException, HttpMessageNotWritableException {
		OutputStream out = httpOutputMessage.getBody();
		String text = JSON.toJSONString(invokeResult, features);
		System.out.println(">>>writeInternal:" + text);
		out.write(text.getBytes());
	}

	public Charset getCharset() {
		return this.charset;
	}

	public void setCharset(Charset charset) {
		this.charset = charset;
	}

	public SerializerFeature[] getFeatures() {
		return features;
	}

	public void setFeatures(SerializerFeature... features) {
		this.features = features;
	}
}
